use itrustee_attester::config::ITrusteeConfig;
use plugin_manager::PluginError;

pub const TEST_UUID: &str = "4f84c0e0-4c3f-422f-97dc-14bfa2314ad1";

/// Generate invalid configuration JSON (missing uuid field)
pub fn get_invalid_config_json_missing_uuid() -> String {
    r#"{
        "other_field": "some_value"
    }"#
    .to_string()
}

/// Generate invalid configuration JSON (wrong uuid field type)
pub fn get_invalid_config_json_wrong_type() -> String {
    r#"{
        "uuid": 12345
    }"#
    .to_string()
}

/// Generate invalid JSON format
pub fn get_invalid_json_format() -> String {
    r#"{
        "uuid": "550e8400-e29b-41d4-a716-446655440000",
        "missing_closing_brace
    "#
    .to_string()
}

// Mock function to simulate query_configuration
pub fn mock_query_configuration_success(plugin_type: String) -> Option<String> {
    if plugin_type == "itrustee" {
        Some(get_valid_config_json())
    } else {
        None
    }
}

pub fn mock_query_configuration_not_found(_plugin_type: String) -> Option<String> {
    None
}

/// Generate valid test configuration JSON
pub fn get_valid_config_json() -> String {
    format!(
        r#"{{
        "uuid": "{}"
    }}"#,
        TEST_UUID
    )
}

/// Test successful JSON configuration parsing
#[test]
fn test_itrusteeconfig_from_json_success() {
    let plugin_type = "itrustee".to_string();
    let config_json = get_valid_config_json();

    let result = ITrusteeConfig::from_json(plugin_type, &config_json);

    assert!(result.is_ok(), "Should successfully parse valid config JSON");

    let config = result.unwrap();
    assert_eq!(config.plugin_type, "itrustee");
    assert_eq!(config.ta_uuid, TEST_UUID);
}

/// Test JSON configuration with missing uuid field
#[test]
fn test_itrusteeconfig_from_json_missing_uuid() {
    let plugin_type = "itrustee".to_string();
    let config_json = get_invalid_config_json_missing_uuid();

    let result = ITrusteeConfig::from_json(plugin_type, &config_json);

    assert!(result.is_err(), "Should fail when uuid field is missing");
}

/// Test JSON configuration with wrong uuid field type
#[test]
fn test_itrusteeconfig_from_json_invalid_uuid_type() {
    let plugin_type = "itrustee".to_string();
    let config_json = get_invalid_config_json_wrong_type();

    let result = ITrusteeConfig::from_json(plugin_type, &config_json);

    assert!(result.is_err(), "Should fail when uuid field has wrong type");

    match result.unwrap_err() {
        PluginError::InputError(msg) => {
            assert!(msg.contains("uuid"), "Error message should mention uuid: {}", msg);
        },
        _ => panic!("Should return InputError for wrong uuid type"),
    }
}

/// Test invalid JSON format
#[test]
fn test_itrusteeconfig_from_json_invalid_json() {
    let plugin_type = "itrustee".to_string();
    let config_json = get_invalid_json_format();

    let result = ITrusteeConfig::from_json(plugin_type, &config_json);

    assert!(result.is_err(), "Should fail for invalid JSON format");

    match result.unwrap_err() {
        PluginError::InternalError(msg) => {
            assert!(
                msg.contains("Failed to parse plugin configuration as JSON") || msg.contains("JSON"),
                "Error message should mention JSON parsing failure: {}",
                msg
            );
        },
        _ => panic!("Should return InternalError for invalid JSON"),
    }
}

/// Test configuration parsing with different plugin types
#[test]
fn test_itrusteeconfig_different_plugin_types() {
    let valid_json = get_valid_config_json();
    let plugin_types = vec!["itrustee", "custom_type", "test_plugin"];

    for plugin_type in plugin_types {
        let result = ITrusteeConfig::from_json(plugin_type.to_string(), &valid_json);
        assert!(result.is_ok(), "Should work with any plugin type string");

        let config = result.unwrap();
        assert_eq!(config.plugin_type, plugin_type);
        assert_eq!(config.ta_uuid, TEST_UUID);
    }
}

/// Test configuration with empty uuid value
#[test]
fn test_itrusteeconfig_empty_uuid() {
    let plugin_type = "itrustee".to_string();
    let config_json = r#"{
        "uuid": ""
    }"#;

    let result = ITrusteeConfig::from_json(plugin_type, config_json);

    assert!(result.is_ok(), "Empty string uuid should be parsed (validation happens later)");

    let config = result.unwrap();
    assert_eq!(config.plugin_type, "itrustee");
    assert_eq!(config.ta_uuid, "");
}

/// Test configuration with additional fields (should be ignored)
#[test]
fn test_itrusteeconfig_with_extra_fields() {
    let plugin_type = "itrustee".to_string();
    let config_json = format!(
        r#"{{
        "uuid": "{}",
        "extra_field": "should_be_ignored",
        "another_field": 123,
        "nested_field": {{
            "data": "value"
        }}
    }}"#,
        TEST_UUID
    );

    let result = ITrusteeConfig::from_json(plugin_type, &config_json);

    assert!(result.is_ok(), "Should ignore extra fields and parse successfully");

    let config = result.unwrap();
    assert_eq!(config.plugin_type, "itrustee");
    assert_eq!(config.ta_uuid, TEST_UUID);
}

/// Test configuration parsing error handling
#[test]
fn test_itrusteeconfig_error_messages() {
    let plugin_type = "itrustee".to_string();

    // Test with malformed JSON
    let malformed_json = r#"{"uuid": ""test""#;
    let result = ITrusteeConfig::from_json(plugin_type.to_string(), malformed_json);
    assert!(result.is_err());

    // Test with uuid as null
    let null_uuid_json = r#"{"uuid": null}"#;
    let result = ITrusteeConfig::from_json(plugin_type.to_string(), null_uuid_json);
    assert!(result.is_err());

    // Test with uuid as array
    let array_uuid_json = r#"{"uuid": ["not", "a", "string"]}"#;
    let result = ITrusteeConfig::from_json(plugin_type.to_string(), array_uuid_json);
    assert!(result.is_err());
}
